package com.zengge.zbc.utils;


import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AesUtils {

    private final static String AES = "AES/";
    //算法模式
    private final static String CBC_ALGORITHM_MODE = "CBC/";

    //补码类型
    public final static String PKC_S7_PADDING_MODE = "PKCS7Padding";
    public final static String PKC_S5_PADDING_MODE = "PKCS5Padding";


    private Base64.Encoder encoder;
    private Base64.Decoder decoder;
    private IvParameterSpec ivParameterSpec;
    private SecretKeySpec secretKeySpec;

    public AesUtils(String secretKey, String space) throws Exception {

        encoder = Base64.getEncoder();
        decoder = Base64.getDecoder();


        ivParameterSpec = new IvParameterSpec(space.getBytes());
        secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "AES");
    }


    private byte[] encryptDoFinal(byte[] value) throws Exception {
        Cipher cipherCBCEncrypt = Cipher.getInstance(AES + CBC_ALGORITHM_MODE + PKC_S5_PADDING_MODE);
        cipherCBCEncrypt.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        return cipherCBCEncrypt.doFinal(value);
    }

    private byte[] decryptDoFinal(byte[] value) throws Exception {
        Cipher cipherCBCDecrypt = Cipher.getInstance(AES + CBC_ALGORITHM_MODE + PKC_S5_PADDING_MODE);
        cipherCBCDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        return cipherCBCDecrypt.doFinal(value);
    }


    /**
     * CBC encrypt
     *
     * @param value value
     * @return String
     * @throws Exception Exception
     */
    public String cbcEncrypt(String value) throws Exception {
        return encoder.encodeToString(encryptDoFinal(value.getBytes()));
    }


    public String cbcEncryptToHex(String value) throws Exception {
        return ByteUtil.bytesToHexString(encryptDoFinal(value.getBytes("utf-8")));
    }

    /**
     * CBC decrypt
     *
     * @param value value
     * @return String
     * @throws Exception Exception
     */
    public String cbcDecrypt(String value) throws Exception {
        return new String(decryptDoFinal(decoder.decode(value.getBytes())));
    }


    public String cbcDecryptToHex(String value) throws Exception {
        byte[] str = ByteUtil.hexStringToBytes(value);
        return new String(decryptDoFinal(str),"utf-8");
    }
}




























